package prj.stars;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

/**
 * GroupActivity represents the activity that takes care of each group of students and changes made both to students 
 * and group. It receives the group name through an intent from main activity, Grades activity.
 * 
 * Options for updates on students and group: add a student (add button pop-ups a dialog box which requires the name 
 * of the student to be added); remove a student (by long-clicking on it in the list displayed; a pop-up asks for 
 * confirmation); update information of students (stars, presence and maybe grades of tests/homework). All the changes 
 * will be permanent only after clicking commit button. The list of students is scrollable also horizontally, for there
 * may be a lot of columns with information for each student. 
 * 
 * @author Andreea-Cristina Hodea
 *
 */
public class GroupActivity extends ListActivity{
	
	private GroupAdapter adapter;
	private final int UPDATE_STUDENT_INFO = 0, DIALOG_CONFIRM_REMOVE = 1, DIALOG_ADD_STUDENT = 2;
	private CharSequence[] options = {"add star", "add presence"};
	private boolean[] selections = new boolean[options.length];
	private GroupMember student;
	private String group;
	private boolean modified = false;
	
	 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.liststudents);
        adapter = new GroupAdapter(this);
        setListAdapter(adapter);
        
        Intent intent = getIntent();
        group = intent.getStringExtra("group");        
        getStudentsFromFile(group, true);
        options[0] = getString(R.string.addStars);
        options[1] = getString(R.string.addPresence);
        
        getListView().setOnItemClickListener(new OnItemClickListener() {
        	public void onItemClick(AdapterView<?> listAdapter, View view, int position, long id) {
        		student = (GroupMember)adapter.getItem(position);
        		showDialog(UPDATE_STUDENT_INFO);
        	}
        });
        
        getListView().setOnItemLongClickListener(new OnItemLongClickListener() {
			public boolean onItemLongClick(AdapterView<?> listAdapter, View view, int position, long id) {				
				student = (GroupMember)adapter.getItem(position);				
				showDialog(DIALOG_CONFIRM_REMOVE);				
				return true;
			}
		});
        
        /* Buttons for adding student and commit changes. */
        Button commitB = (Button)findViewById(R.id.commitChangesButton);
        commitB.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				if (modified) {
					saveStudentsToLocalFile(group);
					modified = false;
				}
			}
		});
        
        Button addButton = (Button)findViewById(R.id.addNewStudentButton);
        addButton.setOnClickListener(new OnClickListener() {
			
			public void onClick(View v) {
				showDialog(DIALOG_ADD_STUDENT);
			}
		});
    }
    
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setContentView(R.layout.liststudents);
      }
    
    /**
     * Given the group name, a possible input file may have the name "grupa<group_name>.txt".
     * 
     * @param group group name
     * @return filename
     */
    private String determineFilename(String group) {
    	return "grupa"+ group.toLowerCase()+".txt";
    }
    
    /**
     * Given a group name, looks for a file either in assets or in memory. If this file exists, it is supposed to have 
     * lines in the following format: student_name: stars, presence. For each entry of this kind, add students to known
     * students of this group through the adapter. 
     * 
     * @param group group name
     * @param fromAssets true if input file should be found in the assets directory.
     */
    public void getStudentsFromFile(String group, boolean fromAssets) {
    	String filename = determineFilename(group);    	
    	BufferedReader in = null;
    	try {
    		if (fromAssets) {
	    		AssetManager am = getAssets();
				in = new BufferedReader(new InputStreamReader(am.open(filename)));
    		}
    		else 
    			in = new BufferedReader(new InputStreamReader(openFileInput(filename)));
			String line;
			while((line = in.readLine()) != null) {
				int index = line.indexOf(":");
				if (index > 0) {
					String name = line.substring(0, index);
					line = line.substring(index+2).replace(" ", "");
					String[] params = line.split(",");
					
					if (params.length > 0) {
						GroupMember student = new GroupMember(name, Integer.parseInt(params[0]), Integer.parseInt(params[1]));
						adapter.addGroupMember(student);			
									        
				        Log.i("Added student to group "+group, student.toString());
					}			        
				}
			}
		} catch (IOException e) {
			if (!fromAssets) {				
				getStudentsFromFile(group, true);
			}
		}catch (Exception e) {
			//some other exception happened, maybe due to format of input in file.
			e.printStackTrace();
		}finally {
			if (in != null)
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
    }
    
    public void saveStudentsToLocalFile(String group) {
    	String filename = determineFilename(group);
    	BufferedWriter out = null;
    	try {
			out = new BufferedWriter(new OutputStreamWriter(openFileOutput(filename, MODE_WORLD_WRITEABLE)));
			for (int i = 0, n = adapter.getCount(); i < n; i++) {
				String output = ((GroupMember)(adapter.getItem(i))).toString(); 
				out.append(output);
				out.newLine();
				out.flush();
			}
			Toast.makeText(this, R.string.changesCommitedToast, Toast.LENGTH_SHORT).show();
		} catch (FileNotFoundException e) {
			Log.e("EXCEPTION FileNotFound", filename);
		} catch (IOException e) {
			Log.e("EXCEPTION Write to file", filename);
		}finally {
			if (out != null)
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
    	
    }
    
    /**
     * Dialogs for modifying students information or group structure. If something changes, it modified comes to true, 
     * so that when a commit is desired, changes should be saved to file only if modified is true.
     */
    public Dialog onCreateDialog(final int id) {
    	String title;
    	switch(id) {
    		case DIALOG_ADD_STUDENT: 
    			LayoutInflater factory = LayoutInflater.from(this);
    			final View textEntryView = factory.inflate(R.layout.addstudent, null);    			
    			title = getString(R.string.dialogAddStudentTitle);
    			
    			return new AlertDialog.Builder(this)
    			.setTitle(title + group)
    			.setView(textEntryView)
    			.setPositiveButton(R.string.dialogAddStudentOk, new DialogInterface.OnClickListener() {
    				public void onClick(DialogInterface dialog, int which) {
    					EditText name = (EditText)textEntryView.findViewById(R.id.dialogStudentName);

    					if (name.getText().length() > 0) 
    						if (adapter.addGroupMember(new GroupMember(name.getText().toString()))) {
	    						modified = true;
	    						String text = " " + getString(R.string.addedStudentToast);
	    						Toast.makeText(GroupActivity.this, name + text, Toast.LENGTH_LONG);
    						}
    				}
    			})
    			.setNegativeButton(R.string.cancelButton, new DialogInterface.OnClickListener() {
    				public void onClick(DialogInterface dialog, int which) {}
    			}).create();
    		
    		case UPDATE_STUDENT_INFO:
    			title = getString(R.string.updateStudentInfoTitle) + " ";
    	    	return new AlertDialog.Builder(this)
    	    			.setTitle(title + student.getStudent())
    	    			.setMultiChoiceItems(options, selections, new DialogInterface.OnMultiChoiceClickListener() {
    						public void onClick(DialogInterface dialog, int which, boolean isChecked) {					}
    					})
    					.setPositiveButton(R.string.okButton, new DialogButtonClicked())
    					.setNegativeButton(R.string.cancelButton, new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int which) {}})
    	    			.create();
    		case DIALOG_CONFIRM_REMOVE:
    			title = getString(R.string.removeStudentConfirmationTitle);
    			return new AlertDialog.Builder(this)
    			.setTitle(title + " " + student.getStudent() + "?")
    			.setPositiveButton(R.string.okButton, new DialogInterface.OnClickListener() {					
					public void onClick(DialogInterface dialog, int which) {
						String name = student.getStudent();
						if (adapter.removeGroupMember(student)) {
							modified = true;							
							String text = " " + getString(R.string.studentRemovedMessage) + " ";
							Toast.makeText(GroupActivity.this, name + text + group, Toast.LENGTH_SHORT).show();
						}
					}
				})
				.setNegativeButton(R.string.cancelButton, new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog, int which) {}
				})
    			.create();
    	}
    	return null;
    }
    
    class DialogButtonClicked implements DialogInterface.OnClickListener {
    	public void onClick(DialogInterface dialog, int which) {
			if (which == DialogInterface.BUTTON_POSITIVE) {
				if (selections[0]) {
					student.setStars(student.getStars()+1);
					modified = true;
				}
				if (selections[1]) {
					student.setPresence(student.getPresence()+1);
					modified = true;
				}
				if (modified) {
					adapter.edit();
				}
			}
		}
    }
}
